/**
 * @author Diego Yon 10070
 * Algoritmos y Estructura de Datos
 * Hoja de Trabajo 7
 */

public class BinaryTree<E>
{
	protected E val; // value associated with node
	protected BinaryTree<E> parent; // parent of node
	protected BinaryTree<E> left, right; // children of node
	
	public BinaryTree(){
		// post: constructor that generates an empty node
		val = null;
		parent = null; 
		left = right = this;
	}
	
	public BinaryTree(E value){
		// post: returns a tree referencing value and two empty subtrees
		Assert.pre(value != null, "Tree values must be non-null.");
		val = value;
		right = left = new BinaryTree<E>();
		setLeft(left);
		setRight(right);
	}
	
	public BinaryTree(E value, BinaryTree<E> left, BinaryTree<E> right){
		// post: returns a tree referencing value and two subtrees
		Assert.pre(value != null, "Tree values must be non-null.");
		val = value;
		if (left == null) { left = new BinaryTree<E>(); }
		setLeft(left);
		if (right == null) { right = new BinaryTree<E>(); }
		setRight(right);
	}
	
	public void setLeft(BinaryTree<E> newLeft){
		// post: sets left subtree to newLeft
		// re-parents newLeft if not null
		if (isEmpty()) 
			return;
		if (left != null && left.parent() == this) 
			left.setParent(null);
		left = newLeft;
		left.setParent(this);
	}
	
	public void setRight(BinaryTree<E> newRight){
		// post: sets right subtree to newRight
		// re-parents newRight if not null
		if (isEmpty()) 
			return;
		if (right != null && right.parent() == this) 
			right.setParent(null);
		right = newRight;
		right.setParent(this);
	}
	
	protected void setParent(BinaryTree<E> newParent){
		// post: re-parents this node to parent reference, or null
		if (!isEmpty()) {
			parent = newParent;
		}
	}
	
	public BinaryTree<E> parent(){
		// post: returns reference to parent node, or null
		return parent;
	}
	
	public BinaryTree<E> left(){
		// post: returns reference to (possibly empty) left subtree
		return left;
	}
	
	public BinaryTree<E> right(){
		// post: returns reference to (possibly empty) right subtree
		return right;
	}
	
	public E value(){
		//post: returns value associated with this node
		return val;
	}
	
	public void setValue(E value){
		//post: sets the value associated with this node
		val = value;
	}
	
	public boolean isEmpty(){
		// post: returns true if the OrderedVector is empty
		return left.value() == null && right.value() == null;
	}
}




//public Iterator<E> iterator()
// post: returns an in-order iterator of the elements
//public boolean isLeftChild()
// post: returns true if this is a left child of parent
